﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using System.Web.Routing;
using System.Diagnostics;
namespace JULONG.WEB.Library.Account
{
    using expViewResult;

    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    public class authorityFilter : ActionFilterAttribute
    {
        /// <summary>
        /// 路由是否在名单内
        /// </summary>
        /// <param name="dict"></param>
        /// <returns></returns>
        bool isListItem(RouteData dict)
        {
            var routeForFilter = new routeForFilter(dict);
            foreach (var item in authority.routeList)
            {
                if (item == routeForFilter)
                    return true;
            }
            return false;
        }

        absAuthority authority;

        public authorityFilter(absAuthority authority)
        {
            this.authority = authority;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)//在Action执行前执行  
        {
            //filterContext.HttpContext.Response.Write(@"<br />Before Action Excute" + "\t " + Message);
            //base.OnActionExecuting(filterContext);

            //StackTrace trace = new StackTrace();
            //foreach (StackFrame frame in trace.GetFrames())
            //{
            //    Console.WriteLine(frame.GetMethod().Name);
            //}
            //Console.Read();4

            if (filterContext.IsChildAction)
            {
                return;
            }


            //得到路由信息
            var routeDict = filterContext.RouteData;

            //如果是白名单
            if (authority.filterModel)
            {
                //略过不在名单内的
                if (!isListItem(filterContext.RouteData)) return;
            }
            //如果是黑名单
            else
            {
                //略过在名单内的
                if (isListItem(filterContext.RouteData)) return;
            }

            //如果有权限则跳出
            if (authority.isAuthority(filterContext)) return;

            //默认为view返回
            resultTypeEnum reType = resultTypeEnum.view;
            //取得Action设置的返回
            var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(resultTypeAttribute), false);
            if (attrs.Length > 0) reType = (attrs[0] as resultTypeAttribute).typeenum;

            switch (reType)
            {
                case resultTypeEnum.ajax:

                    filterContext.Result = new JsonResult() { Data = new { info = authority.errorInfo, loginRoute = authority.getLoginRouteValue() } };
                    break;
                case resultTypeEnum.text:

                    filterContext.Result = new ContentResult() { Content = authority.errorInfo };
                    break;

                case resultTypeEnum.richText:

                    filterContext.Result = new ContentResult() { Content = "error|" + authority.errorInfo };
                    break;

                case resultTypeEnum.view:

                    //不能这么写
                    //filterContext.HttpContext.Response.Redirect(authority.getLoginUrl(filterContext) + "?url=" + url, true);

                    filterContext.Result = authority.loginResult(filterContext); // new RedirectToRouteResult("Default", new RouteValueDictionary(new { controller = "vip", action = "login", url = url }), false);

                    //转向到登录界面（这个构造了301永久定向的错误）
                    //re = new RedirectResult(authority.getLoginUrl(filterContext) + "?url=" + url, true);
                    break;

                default:

                    //构造个404
                    filterContext.Result = new JULONG.WEB.Library.expViewResult.NotFoundResult();
                    break;
            }

            filterContext.HttpContext.Response.Clear();
            //filterContext.HttpContext.Response.StatusCode = 302;

            #region 旧代码
            /*
            Type controller = filterContext.Controller.GetType();
            string actionName = filterContext.ActionDescriptor.ActionName;
            var action = controller.GetMethods().FirstOrDefault(d => d.Name.ToLower() == actionName.ToLower());


            //Type returnType = action == null ? null : action.ReturnType;
             * 
            //如果返回值是ActionResult
            if (returnType == typeof(ActionResult))
            {
                //得到请求URL
                //var url = filterContext.HttpContext.Request.Path;
                //if (string.IsNullOrWhiteSpace(url))
                //    url = authority.loginOverUrl(filterContext);

                //不能这么写
                //filterContext.HttpContext.Response.Redirect(authority.getLoginUrl(filterContext) + "?url=" + url, true);

                filterContext.Result = authority.loginResult(filterContext); // new RedirectToRouteResult("Default", new RouteValueDictionary(new { controller = "vip", action = "login", url = url }), false);

                //转向到登录界面（这个构造了301永久定向）
                //re = new RedirectResult(authority.getLoginUrl(filterContext) + "?url=" + url, true);

                filterContext.HttpContext.Response.Clear();
                //filterContext.HttpContext.Response.StatusCode = 302;
            }
            //如果返回值是JsonResult
            else if (returnType == typeof(JsonResult))
            {
                //未写完huohf
                filterContext.Result = new JsonResult();
                filterContext.HttpContext.Response.Clear();
                //filterContext.HttpContext.Response.StatusCode = 304;
            }
            else
            {
                //如果返回值的Result未知则404；
                filterContext.Result = new JULONG.WEB.Library.expViewResult.NotFoundResult();
                filterContext.HttpContext.Response.Clear();
                //filterContext.HttpContext.Response.StatusCode = 404;

            }
*/
            // Certain versions of IIS will sometimes use their own error page when
            // they detect a server error. Setting this property indicates that we
            // want it to try to render ASP.NET MVC's error page instead.
            //filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 
            #endregion

        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)//在Action执行之后执行 
        {
            //输出到输出流中文字：After Action Excute xxx
            //filterContext.HttpContext.Response.Write(@"<br />After Action Excute" + "\t " + Message);
            //base.OnActionExecuted(filterContext);
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)//在Result执行之前   
        {
            //filterContext.HttpContext.Response.Write(@"<br />Before ViewResult Excute" + "\t " + Message);
            //base.OnResultExecuting(filterContext);
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)//在Result执行之后    
        {
            //filterContext.HttpContext.Response.Write(@"<br />After ViewResult Excute" + "\t " + Message);
            //base.OnResultExecuted(filterContext);
        }


    }
}
